package com.ruoyi.report_tg.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.utils.BigDecimalUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.syrw.annotation.FIllBasicInfo;
import com.ruoyi.syrw.common.JiPeiFunction;
import com.ruoyi.syrw.common.LineFunction;
import com.ruoyi.syrw.common.LineUtil;
import com.ruoyi.report_tg.domain.vo.GeneralCharDataVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.report_tg.domain.bo.TdklfxjlbBsInfoBo;
import com.ruoyi.report_tg.domain.vo.TdklfxjlbBsInfoVo;
import com.ruoyi.report_tg.domain.TdklfxjlbBsInfo;
import com.ruoyi.report_tg.mapper.TdklfxjlbBsInfoMapper;
import com.ruoyi.report_tg.service.ITdklfxjlbBsInfoService;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 土的颗粒分析记录Service业务层处理
 *
 * @author zyb
 * @date 2024-05-24
 */
@RequiredArgsConstructor
@Service
@Transactional
public class TdklfxjlbBsInfoServiceImpl implements ITdklfxjlbBsInfoService {

    private final TdklfxjlbBsInfoMapper baseMapper;

    /**
     * 查询土的颗粒分析记录
     */
    @Override
    @FIllBasicInfo
    public TdklfxjlbBsInfoVo queryById(Long excelId) {
        return compute(baseMapper.selectVoById(excelId));
    }

    /**
     * 查询土的颗粒分析记录列表
     */
    @Override
    public TableDataInfo<TdklfxjlbBsInfoVo> queryPageList(TdklfxjlbBsInfoBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TdklfxjlbBsInfo> lqw = buildQueryWrapper(bo);
        Page<TdklfxjlbBsInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询土的颗粒分析记录列表
     */
    @Override
    public List<TdklfxjlbBsInfoVo> queryList(TdklfxjlbBsInfoBo bo) {
        LambdaQueryWrapper<TdklfxjlbBsInfo> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TdklfxjlbBsInfo> buildQueryWrapper(TdklfxjlbBsInfoBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TdklfxjlbBsInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getTotalPage() != null, TdklfxjlbBsInfo::getTotalPage, bo.getTotalPage());
        lqw.eq(bo.getPage() != null, TdklfxjlbBsInfo::getPage, bo.getPage());
        lqw.eq(StringUtils.isNotBlank(bo.getJilbh()), TdklfxjlbBsInfo::getJilbh, bo.getJilbh());
        lqw.eq(StringUtils.isNotBlank(bo.getJiancdwmc()), TdklfxjlbBsInfo::getJiancdwmc, bo.getJiancdwmc());
        lqw.eq(StringUtils.isNotBlank(bo.getGongcbwyt()), TdklfxjlbBsInfo::getGongcbwyt, bo.getGongcbwyt());
        lqw.eq(StringUtils.isNotBlank(bo.getYangpmc()), TdklfxjlbBsInfo::getYangpmc, bo.getYangpmc());
        lqw.eq(StringUtils.isNotBlank(bo.getYangpbh()), TdklfxjlbBsInfo::getYangpbh, bo.getYangpbh());
        lqw.eq(StringUtils.isNotBlank(bo.getYangpsl()), TdklfxjlbBsInfo::getYangpsl, bo.getYangpsl());
        lqw.eq(StringUtils.isNotBlank(bo.getYangpzt()), TdklfxjlbBsInfo::getYangpzt, bo.getYangpzt());
        lqw.eq(bo.getYangpsj() != null, TdklfxjlbBsInfo::getYangpsj, bo.getYangpsj());
        lqw.eq(StringUtils.isNotBlank(bo.getShiyjcrq()), TdklfxjlbBsInfo::getShiyjcrq, bo.getShiyjcrq());
        lqw.eq(StringUtils.isNotBlank(bo.getShiytjwd()), TdklfxjlbBsInfo::getShiytjwd, bo.getShiytjwd());
        lqw.eq(StringUtils.isNotBlank(bo.getShiytjsd()), TdklfxjlbBsInfo::getShiytjsd, bo.getShiytjsd());
        lqw.eq(StringUtils.isNotBlank(bo.getJiancyj()), TdklfxjlbBsInfo::getJiancyj, bo.getJiancyj());
        lqw.eq(StringUtils.isNotBlank(bo.getPandyj()), TdklfxjlbBsInfo::getPandyj, bo.getPandyj());
        lqw.eq(StringUtils.isNotBlank(bo.getZhuyyqsbmcjbh()), TdklfxjlbBsInfo::getZhuyyqsbmcjbh, bo.getZhuyyqsbmcjbh());
        lqw.eq(StringUtils.isNotBlank(bo.getFujsm()), TdklfxjlbBsInfo::getFujsm, bo.getFujsm());
        lqw.eq(bo.getShaiqztzl() != null, TdklfxjlbBsInfo::getShaiqztzl, bo.getShaiqztzl());
        lqw.eq(bo.getXiaoy2mmtzl() != null, TdklfxjlbBsInfo::getXiaoy2mmtzl, bo.getXiaoy2mmtzl());
        lqw.eq(bo.getXiaoy2mmtzztzl() != null, TdklfxjlbBsInfo::getXiaoy2mmtzztzl, bo.getXiaoy2mmtzztzl());
        lqw.eq(bo.getXiaoy2mmqsyzl() != null, TdklfxjlbBsInfo::getXiaoy2mmqsyzl, bo.getXiaoy2mmqsyzl());
        lqw.eq(bo.getMm60ljlstzl() != null, TdklfxjlbBsInfo::getMm60ljlstzl, bo.getMm60ljlstzl());
        lqw.eq(bo.getMm60xygkjtzl() != null, TdklfxjlbBsInfo::getMm60xygkjtzl, bo.getMm60xygkjtzl());
        lqw.eq(bo.getMm60xygkjtzlbfb() != null, TdklfxjlbBsInfo::getMm60xygkjtzlbfb, bo.getMm60xygkjtzlbfb());
        lqw.eq(bo.getMm40ljlstzl() != null, TdklfxjlbBsInfo::getMm40ljlstzl, bo.getMm40ljlstzl());
        lqw.eq(bo.getMm40xygkjtzl() != null, TdklfxjlbBsInfo::getMm40xygkjtzl, bo.getMm40xygkjtzl());
        lqw.eq(bo.getMm40xygkjtzlbfb() != null, TdklfxjlbBsInfo::getMm40xygkjtzlbfb, bo.getMm40xygkjtzlbfb());
        lqw.eq(bo.getMm20ljlstzl() != null, TdklfxjlbBsInfo::getMm20ljlstzl, bo.getMm20ljlstzl());
        lqw.eq(bo.getMm20xygkjtzl() != null, TdklfxjlbBsInfo::getMm20xygkjtzl, bo.getMm20xygkjtzl());
        lqw.eq(bo.getMm20xygkjtzlbfb() != null, TdklfxjlbBsInfo::getMm20xygkjtzlbfb, bo.getMm20xygkjtzlbfb());
        lqw.eq(bo.getMm10ljlstzl() != null, TdklfxjlbBsInfo::getMm10ljlstzl, bo.getMm10ljlstzl());
        lqw.eq(bo.getMm10xygkjtzl() != null, TdklfxjlbBsInfo::getMm10xygkjtzl, bo.getMm10xygkjtzl());
        lqw.eq(bo.getMm10xygkjtzlbfb() != null, TdklfxjlbBsInfo::getMm10xygkjtzlbfb, bo.getMm10xygkjtzlbfb());
        lqw.eq(bo.getMm5ljlstzl() != null, TdklfxjlbBsInfo::getMm5ljlstzl, bo.getMm5ljlstzl());
        lqw.eq(bo.getMm5xygkjtzl() != null, TdklfxjlbBsInfo::getMm5xygkjtzl, bo.getMm5xygkjtzl());
        lqw.eq(bo.getMm5xygkjtzlbfb() != null, TdklfxjlbBsInfo::getMm5xygkjtzlbfb, bo.getMm5xygkjtzlbfb());
        lqw.eq(bo.getMm2ljlstzl() != null, TdklfxjlbBsInfo::getMm2ljlstzl, bo.getMm2ljlstzl());
        lqw.eq(bo.getMm2xygkjtzl() != null, TdklfxjlbBsInfo::getMm2xygkjtzl, bo.getMm2xygkjtzl());
        lqw.eq(bo.getMm2xygkjtzlbfb() != null, TdklfxjlbBsInfo::getMm2xygkjtzlbfb, bo.getMm2xygkjtzlbfb());
        lqw.eq(bo.getMm2zztzlbfb() != null, TdklfxjlbBsInfo::getMm2zztzlbfb, bo.getMm2zztzlbfb());
        lqw.eq(bo.getMm1ljlstzl() != null, TdklfxjlbBsInfo::getMm1ljlstzl, bo.getMm1ljlstzl());
        lqw.eq(bo.getMm1xygkjtzl() != null, TdklfxjlbBsInfo::getMm1xygkjtzl, bo.getMm1xygkjtzl());
        lqw.eq(bo.getMm1xygkjtzlbfb() != null, TdklfxjlbBsInfo::getMm1xygkjtzlbfb, bo.getMm1xygkjtzlbfb());
        lqw.eq(bo.getMm1zztzlbfb() != null, TdklfxjlbBsInfo::getMm1zztzlbfb, bo.getMm1zztzlbfb());
        lqw.eq(bo.getMm0p5ljlstzl() != null, TdklfxjlbBsInfo::getMm0p5ljlstzl, bo.getMm0p5ljlstzl());
        lqw.eq(bo.getMm0p5xygkjtzl() != null, TdklfxjlbBsInfo::getMm0p5xygkjtzl, bo.getMm0p5xygkjtzl());
        lqw.eq(bo.getMm0p5xygkjtzlbfb() != null, TdklfxjlbBsInfo::getMm0p5xygkjtzlbfb, bo.getMm0p5xygkjtzlbfb());
        lqw.eq(bo.getMm0p5zztzlbfb() != null, TdklfxjlbBsInfo::getMm0p5zztzlbfb, bo.getMm0p5zztzlbfb());
        lqw.eq(bo.getMm0p25ljlstzl() != null, TdklfxjlbBsInfo::getMm0p25ljlstzl, bo.getMm0p25ljlstzl());
        lqw.eq(bo.getMm0p25xygkjtzl() != null, TdklfxjlbBsInfo::getMm0p25xygkjtzl, bo.getMm0p25xygkjtzl());
        lqw.eq(bo.getMm0p25xygkjtzlbfb() != null, TdklfxjlbBsInfo::getMm0p25xygkjtzlbfb, bo.getMm0p25xygkjtzlbfb());
        lqw.eq(bo.getMm0p25zztzlbfb() != null, TdklfxjlbBsInfo::getMm0p25zztzlbfb, bo.getMm0p25zztzlbfb());
        lqw.eq(bo.getMm0p075ljlstzl() != null, TdklfxjlbBsInfo::getMm0p075ljlstzl, bo.getMm0p075ljlstzl());
        lqw.eq(bo.getMm0p075xygkjtzl() != null, TdklfxjlbBsInfo::getMm0p075xygkjtzl, bo.getMm0p075xygkjtzl());
        lqw.eq(bo.getMm0p075xygkjtzlbfb() != null, TdklfxjlbBsInfo::getMm0p075xygkjtzlbfb, bo.getMm0p075xygkjtzlbfb());
        lqw.eq(bo.getMm0p075zztzlbfb() != null, TdklfxjlbBsInfo::getMm0p075zztzlbfb, bo.getMm0p075zztzlbfb());
        lqw.eq(bo.getDiljlstzl() != null, TdklfxjlbBsInfo::getDiljlstzl, bo.getDiljlstzl());
        lqw.eq(bo.getDixygkjtzl() != null, TdklfxjlbBsInfo::getDixygkjtzl, bo.getDixygkjtzl());
        lqw.eq(bo.getDixygkjtzlbfb() != null, TdklfxjlbBsInfo::getDixygkjtzlbfb, bo.getDixygkjtzlbfb());
        lqw.eq(bo.getDizztzlbfb() != null, TdklfxjlbBsInfo::getDizztzlbfb, bo.getDizztzlbfb());
        lqw.eq(bo.getD60() != null, TdklfxjlbBsInfo::getD60, bo.getD60());
        lqw.eq(bo.getD30() != null, TdklfxjlbBsInfo::getD30, bo.getD30());
        lqw.eq(bo.getD10() != null, TdklfxjlbBsInfo::getD10, bo.getD10());
        lqw.eq(bo.getBujyxs() != null, TdklfxjlbBsInfo::getBujyxs, bo.getBujyxs());
        lqw.eq(bo.getQulxs() != null, TdklfxjlbBsInfo::getQulxs, bo.getQulxs());
        lqw.eq(bo.getGe60hl() != null, TdklfxjlbBsInfo::getGe60hl, bo.getGe60hl());
        lqw.eq(bo.getGe2le60hl() != null, TdklfxjlbBsInfo::getGe2le60hl, bo.getGe2le60hl());
        lqw.eq(bo.getGe0p75le2hl() != null, TdklfxjlbBsInfo::getGe0p75le2hl, bo.getGe0p75le2hl());
        lqw.eq(bo.getLe0p75hl() != null, TdklfxjlbBsInfo::getLe0p75hl, bo.getLe0p75hl());
        lqw.eq(StringUtils.isNotBlank(bo.getTudjbflhdh()), TdklfxjlbBsInfo::getTudjbflhdh, bo.getTudjbflhdh());
        return lqw;
    }

    /**
     * 新增土的颗粒分析记录
     */
    @Override
    public Boolean insertByBo(TdklfxjlbBsInfoBo bo) {
        TdklfxjlbBsInfo add = BeanUtil.toBean(bo, TdklfxjlbBsInfo.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setExcelId(add.getExcelId());
        }
        return flag;
    }

    /**
     * 修改土的颗粒分析记录
     */
    @Override
    public Boolean updateByBo(TdklfxjlbBsInfoBo bo) {
        TdklfxjlbBsInfo update = BeanUtil.toBean(bo, TdklfxjlbBsInfo.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TdklfxjlbBsInfo entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除土的颗粒分析记录
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public TdklfxjlbBsInfoVo compute(TdklfxjlbBsInfoVo vo) {
        // 1. 参数判断 如果有任何一个为空,则 直接原样返回
        if (BigDecimalUtil.isAnyOneEmpty(vo.getMm60xygkjtzlbfb(), vo.getMm40xygkjtzlbfb(), vo.getMm20xygkjtzlbfb(),
            vo.getMm10xygkjtzlbfb(), vo.getMm5xygkjtzlbfb(), vo.getMm2xygkjtzlbfb(), vo.getMm1zztzlbfb(),
            vo.getMm0p5zztzlbfb(), vo.getMm0p25zztzlbfb(), vo.getMm0p075zztzlbfb())) {
            return vo;
        }
        // 2. 计算
        double[][] data = new double[11][2];
        data[0][1] = vo.getMm60xygkjtzlbfb().doubleValue();
        data[0][0] = 60;
        data[1][1] = vo.getMm40xygkjtzlbfb().doubleValue();
        data[1][0] = 40;
        data[2][1] = vo.getMm20xygkjtzlbfb().doubleValue();
        data[2][0] = 20;
        data[3][1] = vo.getMm10xygkjtzlbfb().doubleValue();
        data[3][0] = 10;
        data[4][1] = vo.getMm5xygkjtzlbfb().doubleValue();
        data[4][0] = 5;
        data[5][1] = vo.getMm2xygkjtzlbfb().doubleValue();
        data[5][0] = 2;
        data[6][1] = vo.getMm1zztzlbfb().doubleValue();
        data[6][0] = 1;
        data[7][1] = vo.getMm0p5zztzlbfb().doubleValue();
        data[7][0] = 0.5;
        data[8][1] = vo.getMm0p25zztzlbfb().doubleValue();
        data[8][0] = 0.25;
        data[9][1] = vo.getMm0p075zztzlbfb().doubleValue();
        data[9][0] = 0.075;
        data[10][1] = 0;
        data[10][0] = 0;
        /**
        // 级配曲线模型
        JiPeiFunction line = LineUtil.getJiPeiFuncLine(data);
        vo.setD10(BigDecimalUtil.defaultValue(line.getD(10), 2));
        vo.setD30(BigDecimalUtil.defaultValue(line.getD(30), 2));
        vo.setD60(BigDecimalUtil.defaultValue(line.getD(60), 2));
        vo.setQulxs(BigDecimalUtil.defaultValue((line.getD(30) * line.getD(30)) / (line.getD(60) * line.getD(10)), 2));
        vo.setBujyxs(BigDecimalUtil.defaultValue(line.getD(60) / line.getD(10), 2));
        vo.setGe60hl(BigDecimalUtil.defaultValue(100 - vo.getMm60xygkjtzlbfb().doubleValue(), 2));
        vo.setGe2le60hl(BigDecimalUtil.subtract(vo.getMm60xygkjtzlbfb(), vo.getMm2xygkjtzlbfb(), 2));
        vo.setGe0p75le2hl(BigDecimalUtil.subtract(vo.getMm2xygkjtzlbfb(), vo.getMm0p075zztzlbfb(), 2));
        vo.setLe0p75hl(BigDecimalUtil.defaultValue(vo.getMm0p075zztzlbfb(), 2));
//        vo.setTudjbflhdh("黏土(GC) 测试");
        // 3.1 画图所需要的 data  参与画线 不展示 不突出辅助线
        List<GeneralCharDataVo> charData = generateData(line);
        // 3.2 其他的点 不参与画线 展示 不突出辅助线
        for (double[] datum : data) {
            charData.add(new GeneralCharDataVo(datum, "010"));
        }
        // 3.3 不参与画线 展示 突出辅助线
        charData.add(new GeneralCharDataVo(new double[]{vo.getD10().doubleValue(), 10}, "011"));
        charData.add(new GeneralCharDataVo(new double[]{vo.getD30().doubleValue(), 30}, "011"));
        charData.add(new GeneralCharDataVo(new double[]{vo.getD60().doubleValue(), 60}, "011"));
        vo.setChartData(charData);
        */
        // mod begin
        // 1. check  Is sorted already?
        // 2. compute D60w
        int i60 = 0;
        int i30 = 0;
        int i10 = 0;
        for (int i = 0; i < data.length; i++) {
            if (data[i][1] > 60) {
                i60 = i;
            }
            if (data[i][1] > 30) {
                i30 = i;
            }
            if (data[i][1] > 10) {
                i10 = i;
            }

        }
        double[][] dataD60 = new double[2][2];
        dataD60[0][0] = data[i60 + 1][0];
        dataD60[0][1] = data[i60 + 1][1];
        dataD60[1][0] = data[i60][0];
        dataD60[1][1] = data[i60][1];
        LineFunction generalLineD60 = LineUtil.getGeneralLine(dataD60);
        vo.setD60(BigDecimalUtil.defaultValue(generalLineD60.getX(60), 2));
        // 3. compute D30
        double[][] dataD30 = new double[2][2];
        dataD30[0][0] = data[i30 + 1][0];
        dataD30[0][1] = data[i30 + 1][1];
        dataD30[1][0] = data[i30][0];
        dataD30[1][1] = data[i30][1];
        LineFunction generalLineD30 = LineUtil.getGeneralLine(dataD30);
        vo.setD30(BigDecimalUtil.defaultValue(generalLineD30.getX(30), 2));
        // 3. compute D10
        double[][] dataD10 = new double[2][2];
        dataD10[0][0] = data[i10 + 1][0];
        dataD10[0][1] = data[i10 + 1][1];
        dataD10[1][0] = data[i10][0];
        dataD10[1][1] = data[i10][1];
        LineFunction generalLineD10 = LineUtil.getGeneralLine(dataD10);
        vo.setD10(BigDecimalUtil.defaultValue(generalLineD10.getX(10), 2));
        vo.setQulxs(BigDecimalUtil.defaultValue((vo.getD30().doubleValue() * vo.getD30().doubleValue()) / (vo.getD60().doubleValue() * vo.getD10().doubleValue()), 2));
        vo.setBujyxs(BigDecimalUtil.defaultValue(vo.getD60().doubleValue() / vo.getD10().doubleValue(), 2));
        vo.setGe60hl(BigDecimalUtil.defaultValue(100 - vo.getMm60xygkjtzlbfb().doubleValue(), 2));
        vo.setGe2le60hl(BigDecimalUtil.subtract(vo.getMm60xygkjtzlbfb(), vo.getMm2xygkjtzlbfb(), 2));
        vo.setGe0p75le2hl(BigDecimalUtil.subtract(vo.getMm2xygkjtzlbfb(), vo.getMm0p075zztzlbfb(), 2));
        vo.setLe0p75hl(BigDecimalUtil.defaultValue(vo.getMm0p075zztzlbfb(), 2));
        // 3.1 画图所需要的 data  参与画线 不展示 不突出辅助线
        List<GeneralCharDataVo> charData = new ArrayList<>(15);
        // 3.2 参与画线 展示 不突出辅助线
        for (int i = 0; i < data.length-1; i++) {
            charData.add(new GeneralCharDataVo(data[i], "100"));
        }
//        // 3.2 其他的点 不参与画线 展示 不突出辅助线
//        for (double[] datum : data) {
//            charData.add(new GeneralCharDataVo(datum, "010"));
//        }
        // 3.3 不参与画线 展示 突出辅助线
        charData.add(new GeneralCharDataVo(new double[]{vo.getD10().doubleValue(), 10}, "011"));
        charData.add(new GeneralCharDataVo(new double[]{vo.getD30().doubleValue(), 30}, "011"));
        charData.add(new GeneralCharDataVo(new double[]{vo.getD60().doubleValue(), 60}, "011"));
        vo.setChartData(charData);
        // mod end
        return vo;
    }

    private List<GeneralCharDataVo> generateData(JiPeiFunction line) {
        List<GeneralCharDataVo> result= new ArrayList<>(600);
        result.add(new GeneralCharDataVo(new double[]{0.075, line.getP(0.075)}, "100"));
        for (double i = 0.1d; i <= 60.5; i += 0.3) {
            result.add(new GeneralCharDataVo(new double[]{BigDecimalUtil.defaultValue(i,2).doubleValue(), line.getP(i)}, "100"));
        }
        return result;
    }

}
